uses Windows;
procedure TCanvas.SetBrush(AValue: TBrush);
begin
  if FBrush=AValue then Exit;
  FBrush:=AValue;
  if (FHandle<>0) and (AValue.FHandle<>0) then
  SelectObject(FHandle,AValue.FHandle)
end;
procedure TCanvas.SetColor(AValue: TColor);
begin
  if FColor=AValue then Exit;
  FColor:=AValue;
  if FHandle=0 then exit;

  //
end;
procedure TCanvas.SetBackgroundColor(AValue: TColor);
begin
  if FBackgroundColor=AValue then Exit;
  FBackgroundColor:=AValue;
  if FHandle=0 then exit;
  ///
end;

function TCanvas.GetPixels(x, y: integer): TColor;
begin
  if FHandle=0 then exit;
  Result:=GetPixel(FHandle,x,y);
end;

procedure TCanvas.SetFont(AValue: TFont);
begin
  if FFont=AValue then Exit;
  FFont:=AValue;
  if (FHandle<>0) and (AValue.FHandle<>0) then SelectObject(FHandle,AValue.FHandle)
end;

procedure TCanvas.SetPen(AValue: TPen);
begin
  if FPen=AValue then Exit;
  FPen:=AValue;
  FPen.FParent:=self;
  if (FHandle<>0) and (AValue.FHandle<>0) then SelectObject(FHandle,AValue.FHandle)
end;

procedure TCanvas.SetPixels(x, y: integer; AValue: TColor);
begin
  if FHandle=0 then exit;
  SetPixel(FHandle,x,y,AValue);
end;

destructor TCanvas.Destroy;
begin
  if FHandle<>0 then
  if FCreated then DeleteDC(FHandle) else
  if FGot<>0 then ReleaseDC(FGot,FHandle);
  FPen.Free;
  FBrush.Free;
  inherited Destroy;
end;

procedure TCanvas.TextOut(X, Y: integer; const Txt: String);
begin
  if FHandle=0 then exit;
  Windows.TextOut(FHandle,x,y,@Txt[1],length(Txt));
end;

procedure TCanvas.LineTo(X, Y: integer);

begin
  if FHandle=0 then exit;
  Windows.MoveToEx(FHandle,OldX,OldY,nil);
  Windows.LineTo(FHandle,X,Y);
end;

procedure TCanvas.MoveTo(X, Y: integer);
begin
  OldX:=X;OldY:=Y;
end;

procedure TCanvas.Rectangle(x1, y1, x2, y2: integer);


begin
  if FHandle=0 then exit;

  Windows.Rectangle(FHandle,X1,Y1,X2,Y2);
end;

procedure TCanvas.FilledRectangle(x1, y1, x2, y2: integer);
begin
  if FHandle=0 then exit;
  Windows.Rectangle(FHandle,X1,Y1,X2,Y2);
end;

procedure TCanvas.ActualizeWin(WindowHandle: THandle);
begin

  if FCreated then if FHandle<>0 then DeleteDC(FHandle) else else
  if FGot<>0 then if FHandle<>0 then ReleaseDC(FGot,FHandle);
  FCreated:=false;
  FHandle:=GetDC(WindowHandle);
  FGot:=WindowHandle;
end;

procedure TCanvas.ActualizeMem;
begin
  if FCreated then if FHandle<>0 then DeleteDC(FHandle) else else
  if FGot<>0 then if FHandle<>0 then ReleaseDC(FGot,FHandle);
  FHandle:=CreateDC('DISPLAY',nil,nil,nil);
  FGot:=0;
  FCreated:=true;
end;


{ TBitmap }

function TBitmap.Getbpp: integer;
var

  BMP:Windows.TBITMAP;
begin
  Result:=0;
  if FHandle=0 then exit;
  GetObject(FHandle,sizeof(BMP),@BMP);
  Result:=BMP.bmBitsPixel;
end;

function TBitmap.GetScanLine(i: integer): Pointer;
var LnSz:integer;
    Buffer: PByteArray;
    BMP:Windows.TBITMAP;
begin
  Result:=nil;
  if FHandle=0 then exit;
  GetObject(FHandle,sizeof(BMP),@BMP);
  LnSz:=((BMP.bmBitsPixel*BMP.bmWidth) div 8);
  if ((BMP.bmBitsPixel*BMP.bmWidth) mod 8)>0 then inc(LnSz);
  if (LnSz mod 2)>0 then inc(LnSz);
  Buffer:=BMP.bmBits;
  Result:=@(Buffer^[i*LnSz]);
end;

function TBitmap.GetHeight: integer;
var
    BMP:Windows.TBITMAP;
    i:integer;

begin
  Result:=0;
  if FHandle=0 then exit;
  GetObject(FHandle,sizeof(BMP),@BMP);
  Result:=BMP.bmHeight;
end;

procedure TBitmap.SetHeight(const AValue: integer);
var Buffer,OldBuffer:PByteArray;
    LnSz,Sz,OldHeight:integer;

    BMP:Windows.TBITMAP;
    FH1:THANDLE;
    i: Integer;
    k: Integer;
    j: Integer;
begin
  if FHandle<>0 then GetObject(FHandle,sizeof(BMP),@BMP);
  if BMP.bmBitsPixel<8 then Raise EInOutError.Create('< 8 bpp will never be supported!');
  OldHeight:=BMP.bmHeight;
  OldBuffer:=BMP.bmBits;
  BMP.bmHeight:=AValue;

  LnSz:=((BMP.bmBitsPixel*BMP.bmWidth) div 8);
  if ((BMP.bmBitsPixel*BMP.bmWidth) mod 8)>0 then inc(LnSz);
  if (LnSz mod 2)>0 then inc(LnSz);

  Sz:=LnSz*AValue;
  Getmem(Buffer,Sz);
  k:=0;
  for i:=0 to Min(AValue,OldHeight) do //todo Optimize
    for j:=0 to LnSz-1 do
      begin
        Buffer^[k]:=OldBuffer^[k];
        inc(k);
      end;
  BMP.bmBits:=Buffer;
  FH1:=CreateBitmapIndirect(BMP);
  DeleteObject(FHandle);
  FHandle:=FH1;
end;

function TBitmap.GetWidth: integer;
var
    BMP:Windows.TBITMAP;
    i:integer;

begin
  Result:=0;
  if FHandle=0 then exit;
  GetObject(FHandle,sizeof(BMP),@BMP);
  Result:=BMP.bmWidth;
end;

procedure TBitmap.SetWidth(const AValue: integer);
var
    Buffer,OldBuffer:PByteArray;
    LnSz,OldLnSz,Sz,OldWidth:integer;
    FHeight:integer;

    BMP:Windows.TBITMAP;
    FH1:THANDLE;

    i: Integer;
    k: Integer;
    j: Integer;
    k1: Integer;
begin

  if FHandle<>0 then GetObject(FHandle,sizeof(BMP),@BMP);
  if BMP.bmBitsPixel<8 then Raise EInOutError.Create('< 8 bpp will never be supported!');
  OldWidth:=BMP.bmWidth;
  OldBuffer:=BMP.bmBits;
  BMP.bmWidth:=AValue;
  FHeight:=BMP.bmHeight;

  LnSz:=((BMP.bmBitsPixel*BMP.bmWidth) div 8);
  if ((BMP.bmBitsPixel*BMP.bmWidth) mod 8)>0 then inc(LnSz);
  if (LnSz mod 2)>0 then inc(LnSz);
  OldLnSz:=((BMP.bmBitsPixel*OldWidth) div 8);
  if ((BMP.bmBitsPixel*OldWidth) mod 8)>0 then inc(LnSz);
  if (OldLnSz mod 2)>0 then inc(OldLnSz);


  Sz:=LnSz*FHeight;
  Getmem(Buffer,Sz);
  k:=0;k1:=0;
  for i:=0 to FHeight do //todo Optimize
    for j:=0 to max(LnSz,OldLnSz)-1 do
      begin
        if j<min(LnSz,OldLnSz) then Buffer^[k]:=OldBuffer^[k1];
        if j<LnSz then inc(k);
        if j<OldLnSz then inc(k1);
      end;

  BMP.bmBits:=Buffer;
  FH1:=CreateBitmapIndirect(BMP);
  DeleteObject(FHandle);
  FHandle:=FH1;
end;

constructor TBitmap.Create;

var Buffer:PByteArray;
    Sz:integer;

begin
  inherited Create;

  Sz:=2*10*10+1;
  Getmem(Buffer,Sz);
  FHandle:=CreateBitmap(10,10,1,16,Buffer);
  Freemem(Buffer,Sz);//We need it?
end;

destructor TBitmap.Destroy;
begin
  if FHandle<>0 then
   DeleteObject(FHandle);
  inherited Destroy;
end;


//TBrush

procedure TBrush.UpdateHandle;
var
  Cnv: TCanvas;
begin

  if FHandleOwned then DeleteObject(FHandle);
  FHandle:=CreateSolidBrush(FColor);//Pen(ord(Style),Width,Color);
  if Handle<>0 then FHandleOwned:=true;
end;

//TPen
procedure TPen.UpdateHandle;
var
  Cnv: TCanvas;
begin

  if FHandleOwned then DeleteObject(FHandle);
  FHandle:=CreatePen(ord(Style),Width,Color);
  if Handle<>0 then FHandleOwned:=true;
end;

procedure TFont.UpdateHandle;
begin
  if FHandleOwned then DeleteObject(Handle);
  FHandle:=CreateFont(Height,0,0,0,iffunc(fsBold in Style,FW_BOLD,FW_DONTCARE),LongInt(LongBool(fsItalic in Style)),
  LongInt(LongBool(fsUnderline in Style)),Longint(LongBool(fsStrikeOut in Style)),Charset,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
  iffunc(Pitch=fpFixed,FIXED_PITCH,iffunc(Pitch=fpDefault,DEFAULT_PITCH,VARIABLE_PITCH)) or FF_DONTCARE,
  PChar(Name));
  if FHandle<>0 then FHandleOwned:=true;
end;

destructor TFont.Destroy;
begin
  inherited Destroy;
  if FHandleOwned then Windows.DeleteObject(Handle);
end;

procedure PrepareGraph;
begin
 //nothing
end;
procedure FinalGraph;
begin
end;


